package com.kelp.codetoolkit.actions

import com.intellij.database.util.common.isNotNullOrEmpty
import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.LangDataKeys
import com.intellij.openapi.actionSystem.PlatformDataKeys
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiField
import com.intellij.psi.PsiJavaFile
import com.kelp.codetoolkit.enums.MySQLDataTypeDefaultValueEnum
import com.kelp.codetoolkit.ui.form.GeneratorDDLDialog
import com.kelp.codetoolkit.utils.NameHandleUtil


/**
 * @author: liuyuebai
 * @date: 2024/10/10 15:25
 * @description:
 */
class FieldToSQLAction: AnAction() {
    override fun actionPerformed(e: AnActionEvent) {
        val project = e.project?:return
        val psiFile = e.getData(LangDataKeys.PSI_FILE)?: return
        if (psiFile is PsiJavaFile){
            val editor = e.getData(PlatformDataKeys.EDITOR)
            if (editor != null) {
                // 获取鼠标点击位置
                val caretModel = editor.caretModel
                val offset = caretModel.offset
                val tableName = getTableName(psiFile)
                // 根据偏移量找到对应的Psi元素
                val elementAt = psiFile.findElementAt(offset)
                if (elementAt is PsiField) {
                    // 现在你已经获取到了 PsiField
                    generatorDDL(project,tableName,elementAt)
                    return
                }
                val psiField = elementAt?.parent
                if (psiField is PsiField) {
                    // 现在你已经获取到了 PsiField
                    generatorDDL(project,tableName,psiField)
                    return
                }
            }
        }
    }

    private fun generatorDDL(project: Project,tableName:String,psiField: PsiField){
        val canonicalText = psiField.type.canonicalText
        val defaultValue = MySQLDataTypeDefaultValueEnum.getTypeDefaultValue(canonicalText)
        val fieldName = NameHandleUtil.camelCaseToUnderscore(psiField.name)
        var docComment = psiField.docComment?.text
        var afterField = ""
        val psiClass = psiField.parent as PsiClass
        val fields = psiClass.fields
        val currentIndex = fields.indexOf(psiField)
        if (currentIndex > 0){
           val foundPrePsiField = fields[currentIndex - 1] as PsiField
            afterField = NameHandleUtil.camelCaseToUnderscore(foundPrePsiField.name)
        }
        docComment = docComment?.replace(Regex("\n|\r\n"), "")
        docComment = docComment?.replace(Regex("/"), "")
        docComment = docComment?.replace(Regex("\\*"), "")
        docComment = docComment?.replace(Regex("\\s+"), "")
        var ddl = "ALTER TABLE `$tableName` ADD COLUMN `$fieldName` ${defaultValue.mType} NOT NULL DEFAULT ${defaultValue.defaultValue} COMMENT '${docComment}'"
        if (fieldName.startsWith("update") && MySQLDataTypeDefaultValueEnum.isLocalDateTime(canonicalText)) {
            ddl = "ALTER TABLE `$tableName` ADD COLUMN `$fieldName` ${defaultValue.mType} NOT NULL DEFAULT ${defaultValue.defaultValue} ON UPDATE CURRENT_TIMESTAMP COMMENT '${docComment}'"
        }
        if (afterField.isNotNullOrEmpty){
            ddl += " AFTER `$afterField`"
        }
        ddl += ";"
        val ddlDialog = GeneratorDDLDialog(ddl,project)
        ddlDialog.show()
    }

    private fun getTableName(psiJavaFile: PsiJavaFile): String {
        val className = getClassName(psiJavaFile)
        if (className != null) {
           return NameHandleUtil.camelCaseToUnderscore(className)
        }
        return ""
    }

    private fun getClassName(psiJavaFile: PsiJavaFile):String? {
      return psiJavaFile.classes[0].name
    }

}